package bluejack.operation;
import bluejack.events.OperationEvent;
import bluejack.operation.Queue;
import nme.errors.Error;
import nme.events.Event;

/**
 * 队列系统
 * 引用defaultQueue将会创建默认queue。而这个默认queue是最常用的，一般情况下不需要再手动创建队列。
 * @author BlueJack
 */

class Queue extends Oper
{
	private static var _defaultQueue:Queue;
	//默认队列
	public static function getDefaultQueue():Queue {
		if (_defaultQueue==null) _defaultQueue = new Queue();
		return _defaultQueue;
	}
	
	public var children:Array<Oper>;

	public function new(children:Array<Oper> = null) {
		super();
		if (children==null) children = [];
		this.children = children;
	}
	
	//推入队列
	public function commitChild(obj:Oper):Void {
		obj.queue = this;
		obj.step = Oper.WAIT;
		children.push(obj);
		if (children.length == 1) doLoad();
	}
	
	//移出队列
	public function haltChild(obj:Oper):Void {
		//如果正在加载，而跳到下一个
		if (obj.step == Oper.RUN) {
			nexthandler();
			return;
		}
		children.remove(obj);
		obj.queue = null;
		obj.step = Oper.NONE;
	}
	
	private function doLoad():Void {
		if (children.length > 0) {
			var oper:Oper = children[0];
			oper.addEventListener(OperationEvent.OPERATION_COMPLETE,nexthandler);
			oper.addEventListener(OperationEvent.OPERATION_ERROR,nexthandler);
			oper.execute();
		}else{
			result();
		}
	}
	
	private function nexthandler(event:Event=null):Void {
		var oper:Oper = children.shift();
		oper.removeEventListener(OperationEvent.OPERATION_COMPLETE,nexthandler);
		oper.removeEventListener(OperationEvent.OPERATION_ERROR,nexthandler);
		if (oper.continueWhenFail || event.type == OperationEvent.OPERATION_COMPLETE) doLoad();
	}
	
	override public function commit(queue:Queue = null):Void {
		if (queue==null) queue = Queue.getDefaultQueue();
		if ( queue == this ) throw new Error("不能将自己推入自己的队列中");
		queue.commitChild(this);
	}
	
	override public function execute():Void {
		super.execute();
		doLoad();
	}
	
	override public function halt():Void {
		super.halt();
		if (children.length > 0) {
			children = children.slice(0, 1);
			children[0].halt();
		}
	}
}